/**
 * strategyMaker
 *
 * @file 策略对象生成器（工厂函数）
 * */

/**
 * StrategyMaker - 策略对象生成器（工厂函数）
 *
 * @class
 * @extends Object
 * */
export const StrategyMaker = function (strategyObj) {
    return {
        strategy: strategyObj,
        /**
         * runOnce - 动态命中并运行策略
         *
         * @function
         * @param { String } key - 指定策略索引
         * @return { any } 策略返回结果
         * @memberOf StrategyMaker
         * */
        runOnce: function (key) {
            return this.strategy[key]();
        },
        /**
         * runGroup - 动态命中并运行策略组
         *
         * @function
         * @param { Array } keyArr - 指定策略索引
         * @return { Array } 策略返回结果组
         * @memberOf StrategyMaker
         * */
        runGroup: function (keyArr) {
            const reArr = [];

            keyArr.forEach(key => {
                reArr.push(this.strategy[key]());
            });

            return reArr;
        },
        /**
         * run - 动态命中并运行策略
         *
         * @function
         * @param { Array | String } key - 指定策略索引
         * @return { Array | any } 策略返回结果
         * @memberOf StrategyMaker
         * */
        run: function (key) {
            return Array.isArray(key) ? this.runGroup(key) : this.runOnce(key);
        },
        /**
         * addOnce - 动态增添一个策略
         *
         * @function
         * @param { String } key - 策略索引
         * @param { any } value - 策略体
         * @return { Boolean } 是否添加成功
         * @memberOf StrategyMaker
         * */
        addOnce: function (key, value) {
            if (this.strategy[key] === void 0) {
                this.strategy[key] = value;
                return true;
            } else {
                return false;
            }
        },
        /**
         * add - 动态新增策略
         *
         * @function
         * @param { Object } strategyObj - 策略组对象
         * @return { Array } 新增策略成功状态组
         * @memberOf StrategyMaker
         * */
        add: function (strategyObj) {
            const that = this;
            const addResultArr = [];

            Object.keys(strategyObj).forEach(key => {
                addResultArr.push({
                    'key': key,
                    'strategy': strategyObj[key],
                    'state': that.addOnce(key, strategyObj[key])
                });
            });

            return addResultArr;
        },
        /**
         * removeOnce - 动态移除一个策略
         *
         * @function
         * @param { String } key - 策略索引
         * @memberOf StrategyMaker
         * */
        removeOnce: function (key) {
            this.strategy[key] = void 0;
        },
        /**
         * remove - 动态移除策略
         *
         * @function
         * @param { Array } keyArr - 策略索引组
         * @memberOf StrategyMaker
         * */
        remove: function (keyArr) {
            keyArr.forEach(key => {
                this.removeOnce(key);
            });
        },
        /**
         * updateOnce - 动态更新一个策略
         *
         * @function
         * @param { String } key - 策略索引
         * @param { any } value - 策略体
         * @memberOf StrategyMaker
         * */
        updateOnce: function (key, value) {
            this.strategy[key] = value;
        },
        /**
         * update - 动态更新策略
         *
         * @function
         * @param { Object } strategyObj - 策略组对象
         * @memberOf StrategyMaker
         * */
        update: function (strategyObj) {
            Object.keys(strategyObj).forEach(key => {
                this.updateOnce(key, strategyObj[key]);
            });
        }
    }
}

export default StrategyMaker
